home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -in_the_mag- / emulation / amiga / uae-0.7.0b2 / src / audio.c next >
C/C++ Source or Header  |  1998-01-20  |  8KB  |  378 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   * OS specific functions
  5.   *
  6.   * Copyright 1995, 1996, 1997 Bernd Schmidt
  7.   * Copyright 1996 Marcus Sundberg
  8.   * Copyright 1996 Manfred Thole
  9.   */
  10.  
  11. #include "sysconfig.h"
  12. #include "sysdeps.h"
  13.  
  14. #include "config.h"
  15. #include "options.h"
  16. #include "memory.h"
  17. #include "custom.h"
  18. #include "gensound.h"
  19. #include "sounddep/sound.h"
  20. #include "events.h"
  21. #include "audio.h"
  22.  
  23. int sound_available = 0;
  24.  
  25. struct audio_channel_data audio_channel[4];
  26.  
  27. int sound_table[256][64];
  28. unsigned long int sample_evtime;
  29.  
  30. void init_sound_table16(void)
  31. {
  32.     int i,j;
  33.  
  34.     for (i = 0; i < 256; i++)
  35.     for (j = 0; j < 64; j++)
  36.         sound_table[i][j] = j * (uae_s8)i * (currprefs.stereo ? 2 : 1);
  37. }
  38.  
  39. void init_sound_table8 (void)
  40. {
  41.     int i,j;
  42.  
  43.     for (i = 0; i < 256; i++)
  44.     for (j = 0; j < 64; j++)
  45.         sound_table[i][j] = (j * (uae_s8)i * (currprefs.stereo ? 2 : 1)) / 256;
  46. }
  47.  
  48. void AUDxDAT(int nr, uae_u16 v)
  49. {
  50. #ifndef DONT_WANT_SOUND
  51.     struct audio_channel_data *cdp = audio_channel + nr;
  52.     cdp->dat = v;
  53.     if (cdp->state == 0 && !(INTREQR() & (0x80 << nr))) {
  54.     cdp->state = 2;
  55.     INTREQ(0x8000 | (0x80 << nr));
  56.     /* data_written = 2 ???? */
  57.     eventtab[ev_aud0 + nr].evtime = cycles + cdp->per;
  58.     eventtab[ev_aud0 + nr].oldcycles = cycles;
  59.     eventtab[ev_aud0 + nr].active = 1;
  60.     events_schedule();
  61.     }
  62. #endif
  63. }
  64.  
  65. #ifdef MULTIPLICATION_PROFITABLE
  66. #define DO_CHANNEL_1(c) do { thisdata = (uae_s8)audio_channel[c].current_sample * audio_channel[c].vol; } while (0)
  67. #define FINISH_DATA(b,logn) do { if (14 - (b) + (logn) > 0) data >>= 14 - (b) + (logn); else data <<= (b) - 14 - (logn); } while (0);
  68. #else
  69. #define DO_CHANNEL_1(c) do { thisdata = sound_table[audio_channel[c].current_sample][audio_channel[c].vol]; } while (0)
  70. #define FINISH_DATA(b,logn)
  71. #endif
  72.  
  73. #ifdef BRANCHES_ARE_EXPENSIVE
  74. #define INIT_ADK(adk) ((adk) | ((adk) >> 4))
  75. #define DO_CHANNEL(c) do { uae_u32 thisdata; DO_CHANNEL_1(c); data += thisdata & (((adk >> c) & 1) - 1); } while (0);
  76. #else
  77. #define INIT_ADK(adk) (adk)
  78. #define DO_CHANNEL(c) do { uae_u32 thisdata; if (! (adk & (0x11 << c))) { DO_CHANNEL_1(c); data += thisdata; } } while (0);
  79. #endif
  80.  
  81. /* Templates! I want templates! */
  82. void sample16_handler(void)
  83. {
  84. #ifndef DONT_WANT_SOUND
  85.     int adk;
  86.     uae_u32 data = SOUND16_BASE_VAL;
  87.  
  88.     eventtab[ev_sample].evtime = cycles + sample_evtime;
  89.     eventtab[ev_sample].oldcycles = cycles;
  90.  
  91.     adk = INIT_ADK (adkcon);
  92.  
  93.     DO_CHANNEL (0);
  94.     DO_CHANNEL (1);
  95.     DO_CHANNEL (2);
  96.     DO_CHANNEL (3);
  97.     FINISH_DATA(16, 2);
  98.     PUT_SOUND_WORD (data);
  99.  
  100.     check_sound_buffers ();
  101. #endif
  102. }
  103.  
  104. void sample8_handler(void)
  105. {
  106. #ifndef DONT_WANT_SOUND
  107.     int adk;
  108.     uae_u32 data = SOUND8_BASE_VAL;
  109.  
  110.     eventtab[ev_sample].evtime = cycles + sample_evtime;
  111.     eventtab[ev_sample].oldcycles = cycles;
  112.  
  113.     adk = INIT_ADK (adkcon);
  114.  
  115.     DO_CHANNEL (0);
  116.     DO_CHANNEL (1);
  117.     DO_CHANNEL (2);
  118.     DO_CHANNEL (3);
  119.     FINISH_DATA(8, 2);
  120.     PUT_SOUND_BYTE (data);
  121.  
  122.     check_sound_buffers ();
  123. #endif
  124. }
  125.  
  126. #ifdef HAVE_STEREO_SUPPORT
  127. void sample16s_handler(void)
  128. {
  129. #ifndef DONT_WANT_SOUND
  130.     int adk;
  131.     uae_u32 data = SOUND16_BASE_VAL;
  132.  
  133.     eventtab[ev_sample].evtime = cycles + sample_evtime;
  134.     eventtab[ev_sample].oldcycles = cycles;
  135.  
  136.     adk = INIT_ADK (adkcon);
  137.  
  138.     DO_CHANNEL (0);
  139.     DO_CHANNEL (3);
  140.     FINISH_DATA (16, 1);
  141.     PUT_SOUND_WORD_RIGHT (data);
  142.  
  143.     data = SOUND16_BASE_VAL;
  144.     DO_CHANNEL (1);
  145.     DO_CHANNEL (2);
  146.     FINISH_DATA (16, 1);
  147.     PUT_SOUND_WORD_LEFT (data);
  148.  
  149.     check_sound_buffers ();
  150. #endif
  151. }
  152.  
  153. void sample8s_handler(void)
  154. {
  155. #ifndef DONT_WANT_SOUND
  156.     int adk;
  157.     uae_u32 data = SOUND8_BASE_VAL;
  158.  
  159.     eventtab[ev_sample].evtime = cycles + sample_evtime;
  160.     eventtab[ev_sample].oldcycles = cycles;
  161.  
  162.     adk = INIT_ADK (adkcon);
  163.  
  164.     DO_CHANNEL (0);
  165.     DO_CHANNEL (3);
  166.     FINISH_DATA (8, 1);
  167.     PUT_SOUND_BYTE_RIGHT (data);
  168.  
  169.     data = SOUND8_BASE_VAL;
  170.     DO_CHANNEL (1);
  171.     DO_CHANNEL (2);
  172.     FINISH_DATA (8, 1);
  173.     PUT_SOUND_BYTE_LEFT (data);
  174.     check_sound_buffers ();
  175. #endif
  176. }
  177. #else
  178. void sample8s_handler(void)
  179. {
  180.     sample8_handler();
  181. }
  182. void sample16s_handler(void)
  183. {
  184.     sample16_handler();
  185. }
  186. #endif
  187.  
  188. static uae_u8 int2ulaw(int ch)
  189. {
  190.     int mask;
  191.  
  192.     if (ch < 0) {
  193.       ch = -ch;
  194.       mask = 0x7f;
  195.     }
  196.     else {
  197.       mask = 0xff;
  198.     }
  199.  
  200.     if (ch < 32) {
  201.     ch = 0xF0 | ( 15 - (ch/2) );
  202.     } else if (ch < 96) {
  203.     ch = 0xE0 | ( 15 - (ch-32)/4 );
  204.     } else if (ch < 224) {
  205.     ch = 0xD0 | ( 15 - (ch-96)/8 );
  206.     } else if (ch < 480) {
  207.     ch = 0xC0 | ( 15 - (ch-224)/16 );
  208.     } else if (ch < 992 ) {
  209.     ch = 0xB0 | ( 15 - (ch-480)/32 );
  210.     } else if (ch < 2016) {
  211.     ch = 0xA0 | ( 15 - (ch-992)/64 );
  212.     } else if (ch < 4064) {
  213.     ch = 0x90 | ( 15 - (ch-2016)/128 );
  214.     } else if (ch < 8160) {
  215.     ch = 0x80 | ( 15 - (ch-4064)/256 );
  216.     } else {
  217.     ch = 0x80;
  218.     }
  219.     return (uae_u8)(mask & ch);
  220. }
  221.  
  222. void sample_ulaw_handler(void)
  223. {
  224. #ifndef DONT_WANT_SOUND
  225.     int nr;
  226.     uae_u32 data = 0;
  227.  
  228.     eventtab[ev_sample].evtime += cycles - eventtab[ev_sample].oldcycles;
  229.     eventtab[ev_sample].oldcycles = cycles;
  230.  
  231.     for (nr = 0; nr < 4; nr++) {
  232.     if (!(adkcon & (0x11 << nr)))
  233.         data += sound_table[audio_channel[nr].current_sample][audio_channel[nr].vol];
  234.     }
  235.     PUT_SOUND_BYTE (int2ulaw (data));
  236.     check_sound_buffers ();
  237. #endif
  238. }
  239.  
  240. #ifndef DONT_WANT_SOUND
  241. static void audio_handler(int nr)
  242. {
  243.     struct audio_channel_data *cdp = audio_channel + nr;
  244.  
  245.     switch (cdp->state) {
  246.      case 0:
  247.     fprintf(stderr, "Bug in sound code\n");
  248.     break;
  249.  
  250.      case 1:
  251.     /* We come here at the first hsync after DMA was turned on. */
  252.     eventtab[ev_aud0 + nr].evtime += maxhpos;
  253.     eventtab[ev_aud0 + nr].oldcycles += maxhpos;
  254.  
  255.     cdp->state = 5;
  256.     INTREQ(0x8000 | (0x80 << nr));
  257.     if (cdp->wlen != 1)
  258.         cdp->wlen--;
  259.     cdp->nextdat = chipmem_bank.wget(cdp->pt);
  260.  
  261.     cdp->pt += 2;
  262.     break;
  263.  
  264.      case 5:
  265.     /* We come here at the second hsync after DMA was turned on. */
  266.     if (currprefs.produce_sound == 0)
  267.         cdp->per = 65535;
  268.  
  269.     eventtab[ev_aud0 + nr].evtime = cycles + cdp->per;
  270.     eventtab[ev_aud0 + nr].oldcycles = cycles;
  271.     cdp->dat = cdp->nextdat;
  272.     cdp->current_sample = (uae_u8)(cdp->dat >> 8);
  273.  
  274.     cdp->state = 2;
  275.     {
  276.         int audav = adkcon & (1 << nr);
  277.         int audap = adkcon & (16 << nr);
  278.         int napnav = (!audav && !audap) || audav;
  279.         if (napnav)
  280.         cdp->data_written = 2;
  281.     }
  282.     break;
  283.  
  284.      case 2:
  285.     /* We come here when a 2->3 transition occurs */
  286.     if (currprefs.produce_sound == 0)
  287.         cdp->per = 65535;
  288.  
  289.     cdp->current_sample = (uae_u8)(cdp->dat & 0xFF);
  290.     eventtab[ev_aud0 + nr].evtime = cycles + cdp->per;
  291.     eventtab[ev_aud0 + nr].oldcycles = cycles;
  292.  
  293.     cdp->state = 3;
  294.  
  295.     /* Period attachment? */
  296.     if (adkcon & (0x10 << nr)) {
  297.         if (cdp->intreq2 && cdp->dmaen)
  298.         INTREQ(0x8000 | (0x80 << nr));
  299.         cdp->intreq2 = 0;
  300.  
  301.         cdp->dat = cdp->nextdat;
  302.         if (cdp->dmaen)
  303.         cdp->data_written = 2;
  304.         if (nr < 3) {
  305.         if (cdp->dat == 0)
  306.             (cdp+1)->per = 65535;
  307.  
  308.         else if (cdp->dat < maxhpos/2 && currprefs.produce_sound < 3)
  309.             (cdp+1)->per = maxhpos/2;
  310.         else
  311.             (cdp+1)->per = cdp->dat;
  312.         }
  313.     }
  314.     break;
  315.  
  316.      case 3:
  317.     /* We come here when a 3->2 transition occurs */
  318.     if (currprefs.produce_sound == 0)
  319.         cdp->per = 65535;
  320.  
  321.     eventtab[ev_aud0 + nr].evtime = cycles + cdp->per;
  322.     eventtab[ev_aud0 + nr].oldcycles = cycles;
  323.  
  324.     if ((INTREQR() & (0x80 << nr)) && !cdp->dmaen) {
  325.         cdp->state = 0;
  326.         cdp->current_sample = 0;
  327.         eventtab[ev_aud0 + nr].active = 0;
  328.         break;
  329.     } else {
  330.         int audav = adkcon & (1 << nr);
  331.         int audap = adkcon & (16 << nr);
  332.         int napnav = (!audav && !audap) || audav;
  333.         cdp->state = 2;
  334.  
  335.         if ((cdp->intreq2 && cdp->dmaen && napnav)
  336.         || (napnav && !cdp->dmaen))
  337.         INTREQ(0x8000 | (0x80 << nr));
  338.         cdp->intreq2 = 0;
  339.  
  340.         cdp->dat = cdp->nextdat;
  341.         cdp->current_sample = (uae_u8)(cdp->dat >> 8);
  342.  
  343.         if (cdp->dmaen && napnav)
  344.         cdp->data_written = 2;
  345.  
  346.         /* Volume attachment? */
  347.         if (audav) {
  348.         if (nr < 3)
  349.             (cdp+1)->vol = cdp->dat;
  350.         }
  351.     }
  352.     break;
  353.  
  354.      default:
  355.     cdp->state = 0;
  356.     eventtab[ev_aud0 + nr].active = 0;
  357.     break;
  358.     }
  359. }
  360.  
  361. void aud0_handler(void)
  362. {
  363.     audio_handler(0);
  364. }
  365. void aud1_handler(void)
  366. {
  367.     audio_handler(1);
  368. }
  369. void aud2_handler(void)
  370. {
  371.     audio_handler(2);
  372. }
  373. void aud3_handler(void)
  374. {
  375.     audio_handler(3);
  376. }
  377. #endif
  378.